package dbPhase.hypeerweb;

import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 * UpdateConnections - reconfigures the connections of a node is something has changed in the HyPeerWeb such
 * as adding or removing a node.
 *
 * @pre Domain: <br>
 * 		connections - array of connections to go through
 * 		conSource - node - where the connections came from.
 * 		conDest - node - where the connections are going to.
 * @author scott44
 *
 */
public abstract class UpdateConnections {

	ArrayList<Connection> connections;
	Node conSource;
	Node conDest;

	/**
	 * UpdateConnections is the constructor for the class and adds all the connections from the source node
	 * so they can be used for the destination node.
	 * @pre node and dp are not null and node is in the HyPeerWeb where dp is being connected to.
	 *
	 * @param node - the source
	 * @param dp - the destination
	 */
	public UpdateConnections(Node node, Node dp) {
		conSource = node;
		conDest = dp;
		connections = new ArrayList<Connection>();
		for (Node n: node.neighbors) {
			connections.add(new NeighborRole(n, node.getSmallestNeighbor()));
		}
		for (Node n: node.upPointers) {
			connections.add(new UpPointerRole(n, node.getSmallestNeighbor()));
		}
		for (Node n: node.downPointers) {
			connections.add(new DownPointerRole(n, node.getSmallestNeighbor()));
		}
		if (node.fold != Node.NULL_NODE) {
			connections.add(new FoldRole(node.fold, node.getSmallestNeighbor()));
		}
		if (node.surrogateFold != Node.NULL_NODE) {
			connections.add(new SurrogateFoldRole(node.surrogateFold, node.getSmallestNeighbor()));
		}
		if (node.inverseSurrogateFold != Node.NULL_NODE) {
			connections.add(new InverseSurrogateFoldRole(node.inverseSurrogateFold, node.getSmallestNeighbor()));
		}
	}

	/**
	 * execute gets the iterator for the connection and calls makeChanges on all the connections
	 *
	 * @pre none
	 *
	 *
	 */
	public void execute() {
		Iterator<Connection> iter = getIterator();
		while (iter.hasNext()) {
			Connection c = iter.next();
			makeChanges(c);
		}
	}

	/**
	 *
	 * @return an iterator for the connections.
	 */
	public Iterator<Connection> getIterator() {
		return connections.iterator();
	}

	/**
	 * makeChanges is a that changes a nodes connections depending on the node.
	 *
	 * @pre c is not null
	 * @param c - the connection to use to make the changes
	 */
	public abstract void makeChanges(Connection c);


}
